package com.kevin.sql;

import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.lang3.StringUtils;

import com.kevin.enums.DBType;

public class SqlInjection {
    final static String filterSqlInjection = "select;into,delete;from,drop;table,drop;database,update;set,truncate;table,create;table,exists;select,insert;into,xp_cmdshell,declare;@,exec;master,waitfor;delay";
    private static ArrayList<String> filterKeyList = null;
	
    static ArrayList<String> getFilterKeyList()
    {
        if (filterKeyList == null)
        {
            filterKeyList = new ArrayList<String>();
            filterKeyList.addAll(Arrays.asList(StringUtils.stripEnd(filterSqlInjection, ",").split(",")));
        }
        return filterKeyList;

    }
	
    static void setFilterKeyList(ArrayList<String> value){
    	filterKeyList = value;
    }
    
	/**
	 * 数据库注入处理
	 * @param text
	 * @param dbType
	 * @return
	 */
	public static String Filter(String text, DBType dbType){
		String[] items = null;
        if (text.indexOf("--") > -1)
        {
            items = text.split("--");
            for (int i = 0; i < items.length - 1; i++)
            {
                if (items[i].split("\'").length % 2 == (i == 0 ? 1 : 0))
                {
                    text = text.replace("--", StringUtils.EMPTY);//name like'% --aaa' --or name='--aa'  前面的 ' 号必须是单数
                    break;
                }
            }
            items = null;
        }
        //foreach (String item in replaceSqlInjection.Split(','))
        //{
        //    text = text.Replace(item, String.Empty);
        //}
        //text = text.Replace("--", "").Replace(";", "").Replace("&", "").Replace("*", "").Replace("||", "");
        items =  text.split(" |(|)");
        if (items.length == 1 && text.length() > 30)
        {
            if (text.indexOf("%20") > -1)
            {
                //Log.WriteLog(true, text);//记录日志
                return "SqlInjection error:" + text;
            }
        }
        else
        {
            switch (dbType)
            {
                case MYSQL:
                case ORACLE:
                case SQLITE:
                    for (int i = 0; i < items.length; i++)//去掉字段的[字段]，两个符号
                    {
                        if (!items[i].startsWith("[#") && items[i].startsWith("[") && items[i].endsWith("]"))
                        {
                            text = text.replace(items[i], items[i].replace("[", StringUtils.EMPTY).replace("]", StringUtils.EMPTY));
                        }
                    }
                    break;
            }
        }
        String lowerText = text.toLowerCase();
        items = lowerText.split(" |(|)");

        int keyIndex = -1;
        boolean isOK = false;
        String tempKey = StringUtils.EMPTY;
        String filterKey = StringUtils.EMPTY;
        String[] filterSpitItems = null;
        for (int i = 0; i < getFilterKeyList().size(); i++)
        {
            filterSpitItems = filterKeyList.get(i).split(";");//分隔
            filterKey = filterSpitItems[0];//取第一个为关键词
            if (filterSpitItems.length > 2)
            {
                continue;
            }
            else if (filterSpitItems.length == 2) // 如果是两个词的。
            {
                keyIndex = Math.min(lowerText.indexOf(filterKey), lowerText.indexOf(filterSpitItems[1]));
            }
            else
            {
                keyIndex = lowerText.indexOf(filterKey);//过滤的关键词或词组
            }
            if (keyIndex > -1)
            {
                for (String item : items) // 用户传进来的每一个单独的词
                {
                    tempKey = StringUtils.strip(item,"\'|!%^");
                    if (tempKey.indexOf(filterKey) > -1 && tempKey.length() > filterKey.length())
                    {
                        isOK = true;
                        break;
                    }
                }
                if (!isOK)
                {
                    //Log.WriteLog(true, FilterKeyList[i] + ":" + text);//记录日志
                    return "SqlInjection error:" + text;
                }
                else
                {
                    isOK = false;
                }
            }
        }
        return text;
	}
}
